package com.xneure.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import com.xneure.utils.cipher.SimpleEncode;
import com.xneure.utils.exception.FormatFileSizeException;

public class FileUtil{
	private static final String[] dw = {"KB","MB","GB","TB","PB","EB","ZB","YB","BB"};

	/**
	 * 转换文件大小 并添加单位
	 */
	public static String formatFileSize(long size){
		if(size < 1024){
			return String.valueOf(size).concat(" Byte");
		}
		int length = dw.length;
		long s = 1;
		for(int i = 0;i < length;i++){
			s *= 1024;
			if(size >= s && size < s * 1024){
				BigDecimal result1 = new BigDecimal(Double.toString(size / s));
				String plainString = result1.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString();
				if(plainString.endsWith(".00")){
					plainString = plainString.substring(0,plainString.length() - 3);
				}
				return plainString.concat(" ".concat(dw[i]));
			}
		}
		throw new FormatFileSizeException("格式化文件大小单位时发生错误，未知的单位类型");
	}

	/**
	 * 获取指定包目录下的文件列表
	 * 
	 * @param resDir
	 * @return List<String>
	 */
	public static List<String> getResourcesJar(String resDir){
		return getResourcesJar(FileUtil.class.getClassLoader(),resDir);
	}

	public static List<String> getResourcesJar(ClassLoader cl,String resDir){
		List<String> list = new ArrayList<String>(10);
		try{
			Enumeration<URL> urls;
			urls = cl.getResources(resDir);
			while(urls.hasMoreElements()){
				URL url = urls.nextElement();
				if(url != null){
					list.add(urlToPath(url));
				}
			}
		}catch(IOException e){
		}
		return list;
	}

	/**
	 * 获取资源文件所在位置 目录或jar
	 * 
	 * @param dir
	 * @return String
	 */
	public static String urlToPath(URL url){
		if(url.getProtocol().equals("file")){
			return url.getFile().substring(1);
		}else if(url.getProtocol().equals("jar")){
			return url.getFile().substring(6,url.getFile().indexOf("!"));
		}else{
			return url.getFile();
		}
	}

	public static byte[] readResource(String resName){
		try{
			FileInputStream is = new FileInputStream(resName);
			return readResource(is);
		}catch(Exception e){
			return null;
		}
	}

	public static byte[] readResource(InputStream is){
		int rLength = 0;
		byte[] b = new byte[1024 * 1024 * 10];
		try{
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			while((rLength = is.read(b)) != -1){
				os.write(b,0,rLength);
			}
			return os.toByteArray();
		}catch(IOException e){
			return null;
		}
	}

	public static byte[] readFile(File f){
		try{
			return FileUtils.readFileToByteArray(f);
		}catch(IOException e){
			return null;
		}
	}

	public static String readFile(File f,String encoding){
		try{
			return FileUtils.readFileToString(f,encoding);
		}catch(IOException e){
			return null;
		}
	}

	public static List<String> readFileLine(File f,String encoding){
		try{
			return FileUtils.readLines(f,encoding);
		}catch(IOException e){
			return null;
		}
	}

	public static boolean writeFile(File f,byte[] data,boolean isAppend){
		try{
			FileUtils.writeByteArrayToFile(f,data,isAppend);
			return true;
		}catch(IOException e){
			e.printStackTrace();
			return false;
		}
	}

	public static boolean writeFile(File f,String data,String encoding,boolean isAppend){
		try{
			FileUtils.writeStringToFile(f,data,encoding,isAppend);
			return true;
		}catch(IOException e){
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 获取class所在的jar 或 目录
	 * 
	 * @param cls
	 * @return File
	 */
	public static File getClassJar(Class<?> cls){
		URL url = cls.getClassLoader().getResource(cls.getPackage().getName().replace(".","/"));
		if(null == url){
			return null;
		}else{
			return new File(urlToPath(url));
		}
	}

	public static String getCurrPath(){
		return getWebPath(FileUtil.class);
	}

	public static String getWebPath(Class<?> cls){
		StringBuilder clsPath;
		if(ServerDetector.ServerType.JBOSS.isServer() || ServerDetector.ServerType.WILDFLY.isServer()){
			clsPath = new StringBuilder(cls.getResource("").getPath());
		}else{
			clsPath = new StringBuilder(cls.getClassLoader().getResource("").getPath());
		}
		int webPath = clsPath.lastIndexOf("/WEB-INF");
		if(webPath > 0){
			clsPath.delete(webPath,clsPath.length() - 1);
		}
		int index = clsPath.lastIndexOf(":");
		if(index > -1){
			clsPath = clsPath.delete(0,index);
		}
		return SimpleEncode.urlDecode(clsPath.toString());
	}

	public static List<FileItem> getUploadFile(){
		return getUploadFile(SpringUtil.getRequest());
	}

	public static List<FileItem> getUploadFile(HttpServletRequest request){
		DiskFileItemFactory factory = new DiskFileItemFactory();
		factory.setSizeThreshold(1024 * 1024 * 200);
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding("utf-8");
		try{
			return upload.parseRequest(request);
		}catch(FileUploadException e){
			return null;
		}
	}
}
